﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Bettzueche.RLLibrary.Component;
using Bettzueche.RLLibrary.Functions;
using Bettzueche.RLLibrary.Types;
using Bettzueche.RLLibrary.Util;

namespace AMEE1
{
    /// <summary>
    /// 
    /// </summary>
    class Agent : SarsaLambda<State, Action>
    {
        #region Standard RL parameters:

        /// <summary>probability of random action = 0.1</summary>
        public const double EPSILON = 0.03;
        /// <summary>step size parameter = 0.3</summary>
        public const double ALPHA = 0.3;
        /// <summary>trace-decay parameter = 0.7</summary>
        public const double LAMBDA = 0.7;
        /// <summary>discount-rate parameters = 1.0</summary>
        public const double GAMMA = 1.0;

        #endregion


        #region Fields

        EpsilonGreedy<Action> _policy;

        #endregion


        #region Properties

        /// <summary>
        /// Gets or sets the epsilon (0.0 bis 1.0). Default: Agent.EPSILON = 0.1.<para>
        /// Explorationsrate: Wahr.keit, nicht die beste Aktion zu wählen</para>
        /// </summary>
        /// <value>
        /// The epsilon.
        /// </value>
        public double Epsilon {
            get { return _policy.Epsilon; }
            set {
                // Was führte zur Designentscheidung, dass Epsilon readonly ist??
                _policy = new EpsilonGreedy<Action>(value);
                base.Policy = _policy;
            }
        }

        #endregion


        #region Constructor(s)

        public Agent(Environment env, QEFunktion qFunc) 
            : this(env, qFunc, new EpsilonGreedy<Action>(Agent.EPSILON))
        {
        }

        private Agent(Environment env, QEFunktion qFunc, GenericExplorationPolicy<Action> policy)
            : base(env, qFunc, policy) 
        {
            _policy = (EpsilonGreedy<Action>)base.Policy;
            this.EFunction = qFunc;
            // Standardwerte:
            base.LearnRate = Agent.ALPHA;
            base.TraceDecay = Agent.LAMBDA;
            base.DiscountFactor = Agent.GAMMA;
        }

        #endregion
        

        #region Methods



        #endregion
    }
}
